#include <memory>
#include <cstdio>

using std::unique_ptr;
using std::shared_ptr;

struct T
{
	T(){printf("-- run here 1:%p!\n",this);}
	T(const T&){printf("-- run here 2:%p!\n",this);}
	const T& operator=(const T&){printf("-- run here 3:%p!\n",this);return *this;}
	~T(){printf("-- end here 1:%p!\n",this);}

	long l;
};

#define CHECKPOINT(p0,p1) \
do\
{\
	printf("\t%s is %p;\n",#p0,p0.get());\
		printf("\t%s is %p;\n",#p1,p1.get());\
}while(0)


void test_move()
{
	unique_ptr<T> p0;
	unique_ptr<T> p1 = std::make_unique<T>();
	//p0 = p1; //error;
	p0 = std::move(p1);
	CHECKPOINT(p0,p1);//p1=NULL;p0指向对象;
}

void test_get()
{
	unique_ptr<T> p0;
	unique_ptr<T> p1(new T);

	p0.reset(p1.get());
	CHECKPOINT(p0, p1);
}

void test_release()
{
	unique_ptr<T> p0;
	unique_ptr<T> p1(new(T));

	p0.reset(p1.release());
	CHECKPOINT(p0, p1);
}

void test_shared_ptr()
{
	shared_ptr<T> p0;
	shared_ptr<T> p1(new T);

	p0.reset(p1.get());
	printf("p0 use count:%ld p1 use count:%ld\n", p0.use_count(), p1.use_count());
	CHECKPOINT(p0, p1);
}

void test_shared_ptr1()
{
	shared_ptr<T> p0;
	shared_ptr<T> p1(new T);

	p0 = p1;
	printf("p0 use count:%ld p1 use count:%ld\n", p0.use_count(), p1.use_count());
	CHECKPOINT(p0, p1);
}

int main(int argc, char ** argv)
{
	//test_move();
//	test_get();
//	test_release();
	/*
	unique_ptr<int> tmp(new int(2));
	int * a = nullptr;
	printf("%d --- %p\n", *tmp, tmp.get());
	a = tmp.release();
	printf("%p --- %d\n", a, *a);
	printf("%p\n", tmp.get());
	*/
//	test_shared_ptr();
//	test_shared_ptr1();
    std::unique_ptr<T> p1 = std::make_unique<T>();
    printf("---%p\n", p1.get());
    p1.reset();
    printf("---%p\n", p1.get());
    p1 = std::make_unique<T>();
    printf("---%p\n", p1.get());

    std::unique_ptr<T> p2;
    printf("2---%p\n", p2.get());
    p2 = std::make_unique<T>();
    printf("2---%p\n", p2.get());
    printf("-------------------------\n");
	return 0;
}
